import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Home-pc
 * Date: 2023-10-21
 * Time: 10:16
 */
class Message{
    public String from;
    public String to;
    public String message;

    //重写tostring方法，便于在服务器日志中读取message的信息
    @Override
    public String toString() {
        return "Message{" +
                "from='" + from + '\'' +
                ", to='" + to + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    private ObjectMapper objectMapper=new ObjectMapper();
    //创建一个数组列表（顺序表），用来存储前端页面输入的信息
    //private List<Message> messageList=new ArrayList<>();
    @Override
    // doPost用来实现 "存档" 功能
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.读取请求中的body，将json格式转化为java格式
        //这里我们使用jackson中的ObjectMapper的readValue方法,在前面我们已经创建出了ObjectMapper对象
        //其输入型参数为请求中的body内容，输出型参数为java类，结果为java类的一个对象
        Message message=objectMapper.readValue(req.getInputStream(),Message.class);
        //2.得到了message信息后，将其存入服务器中
        //messageList.add(message);
        try {
            save(message);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //服务器日志
        System.out.println("服务器收到信息："+message);
        //3.返回响应. (其实不太必要, 主要是返回一个 200 OK 就行了, body 可以没有
        resp.setStatus(200);
        resp.getWriter().write("okkkk");
    }

    private void save(Message message) throws SQLException {
        //通过jdbc，像数据库中存入数据
        //1.连接前的准备工作
        DataSource dataSource=new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/javaMessage?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("1111");
        //2.建立连接
        Connection connection=dataSource.getConnection();
        //3构造SQL
        String sql="insert into message values(?,?,?)";
        PreparedStatement statement= connection.prepareStatement(sql);
        //其中，connection是一个已经建立好的数据库连接对象，sql是一个带有占位符的SQL语句。
        // 通过这个PreparedStatement对象，
        //我们可以使用setXXX()方法来为占位符设置具体的值，然后执行SQL语句。
        // 这样可以避免SQL注入等安全问题，并且可以提高SQL语句的执行效率
        statement.setString(1, message.from);
        statement.setString(2, message.to);
        statement.setString(3, message.message);
        //4.执行sql 写入数据
        statement.executeUpdate();
        //5,释放资源，关闭连接
        statement.close();
        connection.close();
    }

    //实现读档功能
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //将内存中的message信息，组织成json格式，返回到响应中
        List<Message> messageList=null;
        try {
            messageList=load();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        String respJson=objectMapper.writeValueAsString(messageList);
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(respJson);
    }

    private List<Message> load() throws SQLException {
        //通过jdbc，像数据库中存入数据
        //1.连接前的准备工作
        DataSource dataSource=new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/javaMessage?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("1111");
        //2.建立连接
        Connection connection=dataSource.getConnection();
        //3.构造sql语句（load所有资源）
        String sql="select * from message";
        PreparedStatement statement= connection.prepareStatement(sql);
        //4.执行sql语句   Resultset主要用于接收JDBC查询语句返回的数据集对象
        ResultSet resultSet=statement.executeQuery();
        //5.遍历结果，并将其放置到list中，向上一级返回list
        List<Message> messageList=new ArrayList<>();
        while(resultSet.next()){
            //创建一个Message对象
            Message message=new Message();
            message.from=resultSet.getString("from");
            message.to=resultSet.getString("to");
            message.message=resultSet.getString("message");
            messageList.add(message);
        }
        //6.关闭连接，释放资源
        resultSet.close();
        statement.close();
        connection.close();
        //7.返回结果
        return messageList;
    }


}
